%% How the IRIS Preparser Works
% by Jaromir Benes
%
% In this tutorial, we create and preparse various model file examples to
% illustrate the use of the IRIS preparser commands and pseudofunctions.
% Note that we use the `'saveAs='` option in the `model` function to save
% the pre-parsed model files for us to be able to look at what the
% pre-parser commands exactly do.

%% How to Best Run This Tutorial?
%
% Each m-file in this tutorial is split into what is called "code sections"
% in Matlab. A code cell is a shorter block of code performing a specific
% task, separated from other code cells by a double percent sign, `%%`
% (usually with a title and brief introduction added). By default, the
% cells are visually separated from each other by a horizontal rule in the
% Matlab editor.
%
% Instead of running each m-file from the command window, or executing this
% `read_me_first` as a whole, do the following. Open one tutorial m-file in
% the Matlab editor. Arrange the editor window and the command window next
% to each other so that you can see both of them at the same time. Then run
% the m-file cell by cell. This will help you watch closely what exactly
% is going on.
%
% To execute one particular cell, place the cursor in that cell (the
% respective block of code will get highlighted), and select "Run Current
% Section" from a contextual menu (upon a right click on the mouse), or
% pressing a keyboard shortcut (which differ on different systems and
% Matlab versions). To learn more on code sections, search Matlab
% documentation for "code section".

%% Use `!for` Loop to Create Blocks of Code Based on Template
%
% In this model file, we use a `!for...!do...!end` loop to create equations
% for the first differences of some existing variables. The model file can
% be made more compact still; see `example2.model`.

edit example1.model;

% ...
%
% When reading the model file and creating a model object, use the option
% `'saveAs='` <?saveAs?. This option saves the preparsed code (with all
% preparser commands properly executed and expanded) to the specified file.

irisrequired 20140508;

m1 = model('example1.model', ...
    'saveAs=','example1_preparsed.model', ... %?saveAs?
    'mylist=',{'X','Y','Z','A'},'kk=',3) %#ok<NOPTS> %?load?

edit example1_preparsed.model; %?openpreparsed?

%% More Compact `!for` Loop
%
% In this mode file, we create the same model as in `example1.model` using
% the `!for` loop in an even more compact way. We make use of the fact that
% you can have any number of declaration and equations sections; they all
% get simply combined together in the end, in order of their appearance.

edit example2.model;

%% Use `!if` to Create Different Versions of Model File
%
% In this model file, we include two different versions of an equation in
% one model file. Which version is actually loaded and used, depends on a
% condition; the condition is evaluated at the time when the function
% `model` is called to read the model file and when the parameters involved
% in `!if` conditions are assigned particular values.
%
% Note that the syntax of the `!if` command is analogous to the Matlab
% command of the same name; the `!else` clause may be included or omitted.

edit example3.model;

% ...
%
% The `!if` condition in the model file depends on the value of the
% pseudoparameter `stationary`. If a value for the pseudoparameter is not
% supplied at the time of a call to the function `model`, the `!if` command
% behaves as though the condition evaluated to false. As a result, the
% equation `x - x{-1} = rho*(x{-1} - x{-2}) + epsilon` is loaded. Notice
% the warning issued in the command window.

irisrequired 20140508;

m3a = model('example3.model', ...
    'saveAs=','example3a_preparsed.model') %#ok<NOPTS>

edit example3a_preparsed.model;

% ...
%
% Read the model file again. Create a database, assign `false` to the
% pseudoparameter `stationary` in the database <?assignFalse?>, and pass
% the database in when running the `model` function using the option
% `'assign='`. The result is the same as above. Do the same while assigning
% `true` <?assignTrue?>; the other equation, `x = rho*x{-1} + epsilon;` is
% used.

P = struct();
P.stationary = false; %?assignFalse?
m3b = model('example3.model','linear=',true, ...
    'assign=',P,'saveas=','example3b_preparsed.model') %#ok<NOPTS>

edit example3b_preparsed.model;

P.stationary = true; %?assignTrue?
m3c = model('example3.model','linear=',true, ...
    'assign=',P,'saveas=','example3c_preparsed.model') %#ok<NOPTS>

edit example3c_preparsed.model;

% ...
%
% Finally, assign the pseudoparameter `stationary` using its own option;
% the name of the option corresponds to the name of the pseudoparameter
% <?assignOption?>. This is fully equivalent to the above.

m3d = model('example3.model', ...
    'stationary=',true, ... %?assignOption?
    'saveAs=','example3d_preparsed.model') %#ok<NOPTS>

edit example3d_preparsed.model;

%% Use `!switch` to Create Mutliple Versions of Model File
%
% In this model file, we include multiple different versions of an equation
% in one model file. Which version is actually loaded and used, depends on
% an expression; the expression is evaluated at the time when the function
% `model` is called to read the model file and when the parameters involved
% in `!switch` expressions are assigned particular values.
%
% Note that the syntax of the `!switch` command is analogous to the Matlab
% command of the same name; the `!otherwise` clause may be included or
% omitted.

edit example4.model;

% ...
%
% In the model code, a pseudoparameter named `policy_rule` controls which
% equation is included in the final version of the model. First, load the
% model without supplying any value for `policy_rule`. In that case, the
% equation from the `!otherwise` clause is used: `pi = 0`. Notice the
% warning issued in the command window.

irisrequired 20140508;

m4a = model('example4.model', ...
    'saveAs=','example4a_preparsed.model') %#ok<NOPTS>

edit example4a_preparsed.model;

% ...
%
% Assign `'passive_money_rule'` to the pseudoparameter `policy_rule` to
% load the model with the equation `r = 0.8*r{-1} + (1-0.8)*( 4*pi{1} )`.
% Again, there are two ways to assign parameters and pseudoparameters:
% either in a databased passed through the option `'assign='` or through
% itw own option <?assignOption2?>.

P = struct();
P.policy_rule = 'inflation_targeting';

m4b = model('example4.model', ...
    'assign=',P, ... 
    'saveAs=','example4b_preparsed.model') %#ok<NOPTS>

% m4b = model('example4.model', ...
%     'passive_money_rule=','inflation_targeting', ... %?assignOption2?
%     'saveAs=','example4b_preparsed.model') %#ok<NOPTS>

edit example4b_preparsed.model;

% ...
%
% Assign `'passive_money_rule'` to load the model with the equation
% `mu = 0`.

P = struct();
P.policy_rule = 'passive_money_rule';

m4c = model('example4.model', ...
    'assign=',P, ...
    'saveAs=','example4c_preparsed.model') %#ok<NOPTS>

edit example4c_preparsed.model;

% ...
%
% Assign `'active_money_rule'` to load the model with the equation
% `mu = 0.8*mu{-1} + (1-0.8)*( -0.5*y - 0.5*pi )`.

P = struct();
P.policy_rule = 'active_money_rule';

m4d = model('example4.model', ...
    'assign=',P, ...
    'saveAs=','example4d_preparsed.model') %#ok<NOPTS>

edit example4d_preparsed.model;

%% Combine Multiple Model Files Together
%
% In this model file, we use the `!import` command to include the contents
% of another file. The `!import` command allows larger model files to be
% split into logically structured smaller files.

edit example5.model;

% ...
%
% This the model file that is imported into the main file,
% `example5.model`.

edit example5_measurement.model;

% ...
%
% The final model code combines both of the model files.

irisrequired 20140508;

m5 = model('example5.model', ...
    'saveAs=','example5_preparsed.model') %#ok<NOPTS>

edit example5_preparsed.model;

%% Nested Preparser Commands
%
% All preparser commands, such as `!if`, `!switch`, and `!for`, can be
% freely nested (as long as the `!end` commands are properly matched). The
% only limlitation is in using the `!for` loop: the abbreviated syntax
% (with the default name of the control variable being a plain question
% mark, `?`) may not be used when two or more loops are nested; instead,
% the control variable must be given a proper name (such as `?letter` or
% `?#` in the example here).

edit example6.model;

% ...

irisrequired 20140508;

m6 = model('example6.model','linear=',true, ...
    'saveas=','example6_preparsed.model') %#ok<NOPTS>

edit example6_preparsed.model;

%% Pseudofunctions
%
% In this model file, we illustrate the use of the so-called
% pseudofunctions: diff`, `dot`, `difflog`, `movavg`, `movprod`, and
% `movsum`. These are functions that are expanded into a proper text string
% by the preparser; in other words, they do not behave as math functions.

edit example7.model;

% ...

irisrequired 20140508;

m7 = model('example7.model', ...
    'saveAs=','example7_preparsed.model') %#ok<NOPTS>

edit example7_preparsed.model;

%% Use `!export` to Wrap M-File Function as Carry-On Within Model File
%
% In this model file, we include a simple carry-on function that is used in
% the model. When transferring the model file to someone else, we do not
% have to care about including also the m-file -- it is wrapped in the
% model file, and created automatically each time you load the model.

edit example8.model;

% ...

irisrequired 20140508;

m8 = model('example8.model',...
    'saveAs=','example8_preparsed.model') %#ok<NOPTS>

dir *.m;

% ...
%
% If some carry-on files need to be recreated at a later time (for
% instance, because they have been deleted by mistake), simply run the
% function `export`. Notice the warning issued in the command window.

delete myfunction.m;
export(m8);

edit myfunction.m;

%% Pseudosubstitutions
%
% Pseudosubstitutions are expressions that will be evaluated as Matlab
% expressions, and replaced with the resulting value converted to a char
% string. Psuedosubstitutions are enclosed in dollar-brackets, `$[...]$`.
% They must evaluate to a numeric scalar or char string. When used in the
% list of tokens of a `!for` loop, they can also evaluate to a numeric
% vector; in that case, the vector is converted to a comma-separated text
% representation of the numbers.

edit example9.model;

% ...
%
% For the pseudosubstitution in the first part of the `!for` loop in the
% model file to be properly expanded, supply the value for the
% pseudoparameter `K` <?assignK?>. Alternatively, the value for `K` could
% be included in a databased passed through the option `'assign='`.

irisrequired 20140508;

m9 = model('example9.model', ...
    'K=',4, ... %?assignK?
    'saveAs=','example9_preparsed.model');

edit example9_preparsed.model;

%% Publish Tutorial Files to PDFs
%
% The following commands can be used to create PDF versions of the tutorial
% files:

%{
    latex.publish('read_me_first.m',[],'evalCode=',false);
    latex.publish('example1.model');
    latex.publish('example2.model');
    latex.publish('example3.model');
    latex.publish('example4.model');
    latex.publish('example5.model');
    latex.publish('example6.model');
    latex.publish('example7.model');
    latex.publish('example8.model');
    latex.publish('example9.model');
%}
